#include "inf_four_way_key.h"

#include "common_debug.h"

static result_e inf_four_way_key_register_key(void);
static uint8_t  inf_four_way_key_get_press_level(uint8_t btn_id);

four_way_key_t four_way_key; /* 四向按键结构体 */

/**
 * @brief 初始化四向按键模块
 *
 * @return result_e 初始化结果, RESULT_STATUS_OK表示成功, 其他值表示失败
 */
result_e inf_four_way_key_init(void)
{
    /* 初始化按键对象 */
    four_way_key.mode     = KEY_MODE_LUMBAR;
    four_way_key.cur_type = KEY_TYPE_INVALID;
    for (uint8_t i = 0; i < KEY_TYPE_MAX; ++i) {
        four_way_key.callbacks[i] = NULL;
    }

    CHECK_RESULT(inf_four_way_key_register_key(), "Four way key register key fail\n");

    return RESULT_STATUS_OK;
}

/**
 * @brief 设置四向按键的电平
 *
 * @param type  四向按键类型
 * @param level 四向按键电平, 0表示释放（低电平）, 1表示按下（高电平）
 */
result_e inf_four_way_key_set_level(key_type_e type, uint8_t level)
{
    if (type >= KEY_TYPE_MAX) {
        return RESULT_STATUS_INVALID_PARAM;
    }

    /* 分开写判断逻辑只是为了方便阅读 */
    if (level != FOUR_WAY_KEY_PRESS_LEVEL && level != FOUR_WAY_KEY_RELEASE_LEVEL) {
        return RESULT_STATUS_INVALID_PARAM;
    }

    four_way_key.buttons[type].active_level = level;

    return RESULT_STATUS_OK;
}

/**
 * @brief 该函数会不停的扫描按键是否被按下, 放在调度表中循环调度，5ms扫描一次
 *
 */
void inf_four_way_key_handle(void) { common_button_scan(); }

/**
 * @brief 四向按键回调函数
 *
 * @param btn 四向按键结构体指针
 */
static void inf_four_way_key_callbacks(button_t *btn)
{
    if (!btn || btn->id >= KEY_TYPE_MAX) {
        return;
    }

    /* 设置当前按键类型 */
    four_way_key.cur_type = (key_type_e)btn->id;

    /* 执行对应的回调函数 */
    if (four_way_key.callbacks[btn->id]) {
        four_way_key.callbacks[btn->id]();
    }
}

/**
 * @brief 注册按键
 *
 * @return result_e  注册结果, RESULT_STATUS_OK表示成功, 其他值表示失败
 */
static result_e inf_four_way_key_register_key(void)
{
    for (uint8_t i = 0; i < KEY_TYPE_MAX; ++i) {
        four_way_key.buttons[i].id             = (button_id_e)i;
        four_way_key.buttons[i].active_level   = FOUR_WAY_KEY_PRESS_LEVEL; /* 被按下时为高电平 */
        four_way_key.buttons[i].get_gpio_level = inf_four_way_key_get_press_level;
        CHECK_RESULT(common_button_init(&four_way_key.buttons[i]), "Four way key button init fail\n");
        CHECK_RESULT(common_button_register_callback(&four_way_key.buttons[i], BUTTON_EVENT_PRESS_DOWN,
                                                     inf_four_way_key_callbacks),
                     "Four way key register callback fail\n");
    }

    return RESULT_STATUS_OK;
}

/**
 * @brief 获取四向按键被按下时的电平
 *
 * @param   btn_id  四向按键ID
 * @return  uint8_t 四向按键被按下时的电平
 */
static uint8_t inf_four_way_key_get_press_level(uint8_t btn_id)
{
    if (btn_id >= KEY_TYPE_MAX) {
        return FOUR_WAY_KEY_RELEASE_LEVEL;
    }

    return four_way_key.buttons[btn_id].active_level;
}
